import os
import sys
import subprocess
import ctypes
import platform
from datetime import datetime

def is_admin():
    """检查是否以管理员权限运行"""
    try:
        return ctypes.windll.shell32.IsUserAnAdmin()
    except:
        return False

def log_message(log_file, message):
    """记录消息到日志文件（绝对路径）"""
    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    with open(log_file, 'a', encoding='utf-8') as f:
        f.write(f"[{timestamp}] {message}\n")

def run_command(command, log_file, shell=True, capture_output=True):
    """运行系统命令，自动处理换源、权限、缓存问题"""
    try:
        kwargs = {
            'shell': shell, 
            'check': True, 
            'encoding': 'utf-8', 
            'errors': 'replace'
        }
        if capture_output:
            kwargs['stdout'] = subprocess.PIPE
            kwargs['stderr'] = subprocess.PIPE

        # 自动替换为国内镜像源（针对 npm install）
        if "npm install" in command:
            command = command.replace(
                "npm install", 
                "npm install --registry=https://registry.npmmirror.com/ --electron-mirror=https://npmmirror.com/mirrors/electron/"
            )

        result = subprocess.run(command, **kwargs)
        if capture_output:
            stdout = result.stdout.strip() if result.stdout else ""
            return True, stdout
        return True, ""

    except subprocess.CalledProcessError as e:
        stderr = e.stderr.strip() if e.stderr else ""
        # 自动清理缓存（常见 npm 失败解决方案）
        if "EPERM" in stderr or "EACCES" in stderr:
            log_message(log_file, "检测到权限错误，自动清理 npm 缓存...")
            subprocess.run("npm cache clean --force", shell=True, check=False)
        log_message(log_file, f"Command failed: {command}\nError: {stderr}")
        return False, stderr
    except Exception as e:
        log_message(log_file, f"Unexpected error: {str(e)}")
        return False, str(e)

def print_separator():
    print("=" * 50)

def main():
    # 日志文件绝对路径（脚本所在目录）
    script_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
    LOG_FILE = os.path.join(script_dir, "install_log.txt")

    # 初始化日志
    with open(LOG_FILE, 'w', encoding='utf-8') as f:
        f.write(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 安装开始\n")
        f.write(f"系统: {platform.system()} {platform.release()}\n")
        f.write(f"Python: {sys.version.split()[0]}\n")

    print_separator()
    print("   Star Resonance Damage Counter 全自动安装脚本")
    print_separator()
    print("✅ 自动换源 | ✅ 修复权限 | ✅ 智能排错")
    print(f"日志文件: {LOG_FILE}")
    print_separator()

    # 切换到脚本目录
    try:
        os.chdir(script_dir)
    except Exception as e:
        print(f"错误: 无法访问目录 {script_dir}\n{e}")
        log_message(LOG_FILE, f"目录访问失败: {e}")
        input("按回车退出...")
        sys.exit(1)

    # 检查 package.json
    print("[1/5] 检查项目环境...")
    if not os.path.exists("package.json"):
        print("错误: 未找到 package.json！\n当前路径:", os.getcwd())
        log_message(LOG_FILE, "缺少 package.json - 终止安装")
        input("按回车退出...")
        sys.exit(1)

    # 检查 Node.js（最低 v18）
    print("\n[2/5] 检查 Node.js...")
    success, output = run_command("node -v", LOG_FILE)
    if not success:
        print("错误: 未安装 Node.js！\n请从 https://nodejs.org/ 安装 v18+")
        log_message(LOG_FILE, "未找到 Node.js - 终止安装")
        input("按回车退出...")
        sys.exit(1)
    node_version = output.split("v")[1]
    if float(node_version.split(".")[0]) < 18:
        print(f"错误: Node.js 版本过低（当前 {node_version}）\n需要 v18+，请升级后重试")
        sys.exit(1)
    print(f"OK: Node.js v{node_version}")

    # 自动修复权限（针对 Windows）
    print("\n[3/5] 检测非管理员权限，自动提权...")
    if platform.system() == "Windows" and not is_admin():
        ctypes.windll.shell32.ShellExecuteW(
            None, "runas", sys.executable, 
            " ".join(sys.argv), None, 1
        )
        sys.exit(0)

    # 安装主依赖（自动换源）
    print("\n[4/5] 安装主程序依赖...")
    main_ok = 1 if os.path.exists("node_modules/express") else 0
    if not main_ok:
        print("正在运行: npm install（自动切换国内镜像）...")
        success, output = run_command("npm install", LOG_FILE, capture_output=False)
        if success and os.path.exists("node_modules/express"):
            print("✅ 主依赖安装成功")
            log_message(LOG_FILE, "主依赖安装成功")
        else:
            print("错误: 主依赖安装失败！\n日志:", LOG_FILE)
            print("解决方案：\n1. 以管理员运行\n2. 检查网络\n3. 清理缓存: npm cache clean --force")
            input("按回车退出...")
            sys.exit(1)

    # 安装悬浮窗（自动换源 + 单独处理 Electron）
    print("\n[5/5] 安装桌面悬浮窗...")
    overlay_dir = "floating_overlay"
    overlay_ok = 1 if os.path.exists(os.path.join(overlay_dir, "node_modules/electron")) else 0
    if os.path.exists(overlay_dir) and not overlay_ok:
        os.chdir(overlay_dir)
        if os.path.exists("package.json"):
            print(f"正在安装悬浮窗依赖（目录: {os.getcwd()}）...")
            success, output = run_command("npm install", LOG_FILE, capture_output=False)
            if success and os.path.exists("node_modules/electron"):
                print("✅ 悬浮窗安装成功")
                log_message(LOG_FILE, "悬浮窗安装成功")
            else:
                print("⚠️ 悬浮窗安装失败（不影响主程序）\n错误日志:", LOG_FILE)
        os.chdir(script_dir)
    else:
        print("✅ 悬浮窗已安装（跳过）")

    # 安装完成提示
    print_separator()
    print("🎉 全部安装完成！")
    print_separator()
    print("启动方式：")
    print("1. 双击 start.bat → 完整启动器")
    print("2. 双击 一键启动.bat → 快速启动")
    print("3. 浏览器访问: http://localhost:8989")
    print_separator()
    print("日志已保存至:", LOG_FILE)
    log_message(LOG_FILE, "安装流程完成")
    input("按回车退出...")
    sys.exit(0)

if __name__ == "__main__":
    main()